package org.budo.sharding.proxy.recognizer;

import java.util.Collection;
import java.util.LinkedList;

import org.apache.shardingsphere.shardingproxy.backend.communication.jdbc.recognizer.JDBCDriverURLRecognizerEngine;
import org.apache.shardingsphere.shardingproxy.backend.communication.jdbc.recognizer.spi.JDBCDriverURLRecognizer;
import org.budo.support.lang.util.ListUtil;
import org.budo.support.lang.util.ReflectUtil;

import lombok.Getter;
import lombok.NoArgsConstructor;

/**
 * @author lmw
 */
@Getter
@NoArgsConstructor
public class BudoShardingJdbcUrlRecognizer implements JDBCDriverURLRecognizer {
    private Collection<String> URLPrefixes;

    private String driverClassName;

    public BudoShardingJdbcUrlRecognizer(String[] urlPrefix, String driverClassName) {
        this.URLPrefixes = ListUtil.toStringList(urlPrefix);
        this.driverClassName = driverClassName;
    }

    @Override
    public String getDatabaseType() {
        throw new RuntimeException("#30 this=" + this);
    }

    @Override
    public String getDriverClassName() {
        if (null != this.driverClassName) {
            return this.driverClassName;
        }

        LinkedList<JDBCDriverURLRecognizer> jdbcDriverURLRecognizers = jdbcDriverURLRecognizers();
        for (JDBCDriverURLRecognizer each : jdbcDriverURLRecognizers) {
            if (this.isMatchURL(each)) {
                return each.getDriverClassName();
            }
        }

        throw new RuntimeException("#48 this=" + this);
    }

    public static LinkedList<JDBCDriverURLRecognizer> jdbcDriverURLRecognizers() {
        Object URL_RECOGNIZERS = ReflectUtil.getFieldValue(JDBCDriverURLRecognizerEngine.class, "JDBC_DRIVER_URL_RECOGNIZERS");
        LinkedList<JDBCDriverURLRecognizer> jdbcDriverURLRecognizers = (LinkedList<JDBCDriverURLRecognizer>) URL_RECOGNIZERS;
        return jdbcDriverURLRecognizers;
    }

    private boolean isMatchURL(final JDBCDriverURLRecognizer recognizer) {
        if (recognizer.equals(this)) {
            return false;
        }

        for (String each : recognizer.getURLPrefixes()) {
            for (String prefix : this.URLPrefixes) {
                if (prefix.startsWith(each)) {
                    return true;
                }
            }
        }
        return false;
    }
}